﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SaunaClient.Model.Network;
using System.Net;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using SaunaClient.View;
using System.Net.Sockets;
using SaunaClient.Controller.Communication;

namespace SaunaClient.View
{
    public partial class FormSaunaDTestSuite : Form
    {
        private ICommunicationManagerFactory communicationManagerFactory;
        private ICommunicationManager communicationManager;
        private const string COMMUNICATION_MANAGER = "CommunicationManager";


        private const string DEFAULT_FTP_HOST_ADDRESS = "localhost";
        private const int DEFAULT_FTP_PORT_NUMBER = 21;
        private const bool DEFAULT_FTP_USE_SSL = true;
        private const string DEFAULT_FTP_USER_NAME = "SaunaFtpUser";
        private const string DEFAULT_FTP_PASSWORD_NAME = "pass333";
        private const string DEFAULT_FTP_SERVER_DIRECTORY = "/";
        private const string DEFAULT_FTP_LOCAL_DIRECTORY = @"c:\work\";

        private const string DEFAULT_TCP_HOST_ADDRESS = "localhost";
        private const int DEFAULT_TCP_PORT_NUMBER = 1723;
        private const bool DEFAULT_TCP_USE_SSL = true;

        private const string DEFAULT_LOG_FILE_DIRECTORY = @"\";

        public FormSaunaDTestSuite()
        {

            InitializeComponent();
            
            //* Updated Code ******************

            // Make user authentication controller
            communicationManagerFactory = new CommunicationManagerFactoryImplementation();
            communicationManager = communicationManagerFactory.Make(COMMUNICATION_MANAGER);

            // Initialize controls
            textFtpServerDirectory.Text = communicationManager.GetFtpServerDirectory();
            textFtpLocalDirectory.Text = communicationManager.GetFtpLocalDirectory();
                
        }

        private void ButtonUploadFile_Click(object sender, EventArgs e)
        {
            string localDirectory = textFtpLocalDirectory.Text;
            string localFileName = textFtpFileName.Text;
            string serverDirectory = textFtpServerDirectory.Text;

            communicationManager.Upload(localDirectory, localFileName, serverDirectory);
        }

        private void ButtonDownloadFile_Click(object sender, EventArgs e)
        {
            string serverDirectory = textFtpServerDirectory.Text;
            string serverFileName = textFtpFileName.Text;
            string localDirectory = textFtpLocalDirectory.Text;

            communicationManager.Download(serverDirectory, serverFileName, localDirectory);
        }

        private void ButtonGetServerDirectory_Click(object sender, EventArgs e)
        {
            string serverDirectory = textFtpServerDirectory.Text;

            textBoxResult.Text = communicationManager.GetServerFileList(serverDirectory);
        }

        private void ButtonTestFTPS_Click(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// Write ftp base setting to file
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="obj"></param>
        public void WriteToFile(string filePath, object obj)
        {
            using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
            }
        }

        /// <summary>
        /// Read ftp base setting from file
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public object ReadFromFile(string filePath)
        {
            object obj = null;
            try
            {
                using (Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    IFormatter formatter = new BinaryFormatter();
                    obj = formatter.Deserialize(stream);
                }
            }
            catch (FileNotFoundException ex)
            {
                // Write error.
                Console.WriteLine(ex);
            }
            return obj;
        }

        //* Updated Code ******************

        /// <summary>
        /// Option menu event handler
        /// </summary>
        /// <param name="sender">Event sender object</param>
        /// <param name="e">Event arguments</param>
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NetworkSetting networkSetting = communicationManager.ReadConfigFile();
            if (networkSetting == null)
            {
                // When Sauna configuration file does not exist, create network setting with default values
                networkSetting = new NetworkSetting();
            }        

            ClientOptionForm clientOptionForm = new ClientOptionForm(networkSetting);

            if (clientOptionForm.ShowDialog() == DialogResult.OK)
            {
                // End Previous Communication
                communicationManager = null;

                // Recreate Communication Manager
                communicationManager = new CommunicationManager();
                
                networkSetting.Copy(clientOptionForm.networkSetting);
                communicationManager = communicationManagerFactory.Make(COMMUNICATION_MANAGER);

                textFtpServerDirectory.Text = networkSetting.FtpServerDirectory;
                textFtpLocalDirectory.Text = networkSetting.FtpLocalDirectory;
            }

        }

        //* Updated Code ******************

        private void ButtonTcpSendRequest_Click(object sender, EventArgs e)
        {

        }

        private void SendMessage(TcpClient client, String SendData)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(SendData);
            client.GetStream().Write(bytes, 0, bytes.Length);
        }

        private String ReceiveMessage(TcpClient client)
        {
            String receiveData = "";
            bool done = false;

            while (!done)
            {

                byte[] buffer = new byte[4096];
                int totalRead = 0;

                do
                {
                    int readCnt = client.GetStream().Read(buffer, totalRead, buffer.Length - totalRead);
                    totalRead += readCnt;
                } while (client.GetStream().DataAvailable);

                receiveData = Encoding.Unicode.GetString(buffer, 0, totalRead);
                done = true;
            }

            return receiveData;
        }

//* Updated Code ******************

        private const string MESSAGE_LOGIN_GREETING = "Welcome ";
        private const string MESSAGE_EXCLAMATION_MARK = "!";
        private const string MESSAGE_LOGOFF_STATUS = "Logoff Status";

        /// <summary>
        /// Login menu event handler
        /// </summary>
        /// <param name="sender">Event sender object</param>
        /// <param name="e">Event arguments</param>
        private void loginToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoginForm loginForm = new LoginForm(communicationManager);

            if (loginForm.ShowDialog() == DialogResult.OK)
            {
                // Login succeed
                EnableClientGuiControls();
                ShowGreetingMessage(loginForm.LoginId);
            }

        }

        /// <summary>
        /// Logoff menu event handler
        /// </summary>
        /// <param name="sender">Event sender object</param>
        /// <param name="e">Event arguments</param>
        private void logoffToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Logoff
            // Disable Client Gui Controls
            DisableClientGuiControls();
            ShowLogoffStatusMessage();
        }

        /// <summary>
        /// Enable Client Gui Controls
        /// </summary>
        private void EnableClientGuiControls() 
        {
            ButtonDownloadFile.Enabled = true;
            ButtonUploadFile.Enabled = true;
            ButtonGetServerDirectory.Enabled = true;
        }

        /// <summary>
        /// Disable Client Gui Contorls
        /// </summary>
        private void DisableClientGuiControls()
        {
            ButtonDownloadFile.Enabled = false;
            ButtonUploadFile.Enabled = false;
            ButtonGetServerDirectory.Enabled = false;
        }
        
        /// <summary>
        /// Show Lonin Greeting Message
        /// </summary>
        private void ShowGreetingMessage(string loninId)
        {
            labelGreetingMessage.Text = 
                MESSAGE_LOGIN_GREETING + loninId + MESSAGE_EXCLAMATION_MARK;

        }

        /// <summary>
        /// Show Logoff Message
        /// </summary>
        private void ShowLogoffStatusMessage()
        {
            labelGreetingMessage.Text = MESSAGE_LOGOFF_STATUS;
        }

    }

}
